定义
装饰模式是为已有功能动态地添加更多功能的一种方式。
介绍
由定义,给一个类或对象添加功能,为了不破坏类的结构,可以有两种方式:
继承
使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
关联
将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)
UML
示例代码
abstract class Component {
public abstract void Operation();
}
public class ConcreateComponent extends Component {
@Override
public void Operation() {
// TODO Auto-generated method stub
System.out.println("basic operation");
}
}
public class Decorator extends Component {
protected Component component;
public void SetComponent(Component component) {
this.component = component;
}
@Override
public void Operation() {
// TODO Auto-generated method stub
if (component != null) {
component.Operation();
}
}
}
public class DecoratorA extends Decorator {
@Override
public void Operation() {
// TODO Auto-generated method stub
super.Operation();
newBehavior();
}
private void newBehavior() {
System.out.println("Add new behavior AAA");
}
}
public class DecoratorB extends Decorator {
@Override
public void Operation() {
// TODO Auto-generated method stub
super.Operation();
newBehavior();
}
private void newBehavior() {
System.out.println("Add new behavior BBB");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ConcreateComponent c = new ConcreateComponent();
DecoratorA a = new DecoratorA();
DecoratorB b = new DecoratorB();
a.SetComponent(c);
a.Operation();
b.SetComponent(a);
b.Operation();
}
//输出
basic operation
Add new behavior AAA
basic operation
Add new behavior AAA
Add new behavior BBB
基本思路是,在ConcreateComponent做一些基本操作,然后创建装饰器,如果需要给对象增加新的特性,就把该对象放入对应的装饰器中。
尽量保持Component作为一个轻类,不要做太多逻辑。
评价
优缺点
优点
- 不会破坏类的封装性,而且耦合性比继承要低,灵活性比继承高。
- 可以动态的拓展一个对象的功能。
- 可以用多个装饰器按照不同顺序组合出不同的对象。
- 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类。符合开闭原则。
缺点
- 需要创建更多的对象。
- 因为装饰器使用灵活,使用的顺序也能不同,可能引起的错误会比较隐蔽。
使用场景
当系统需要新功能的时候,如果新功能只是为了满足某个条件下才会执行的行为,则不建议修改原类,而是使用装饰模式,把要装饰的功能放在特定类中,然后用这个类包装它所要装饰的对象。这样,客户代码可以根据情况在运行时选择装饰功能包装对象。